﻿#ifndef BMPFILE_H
#define BMPFILE_H

#include "logger.h"
#include "commonmarco.h"
#include "cpoint.h"
#include "database.h"

#include <iostream>
#include <cstdlib>
#include <cmath>
#include <vector>

#include <QFile>
#include <QSharedPointer>
#include <QScopedPointer>
#include <QMutex>
#include <QMutexLocker>
#include <QException>
#include <QList>

typedef QSharedPointer<QFile> file_type;
class BMPFile;
typedef bool (BMPFile::* StepFuncPtr)(void);
typedef QSharedPointer<DataBase> database_type;
class BMPFile
{
public:
    BMPFile();
    virtual ~BMPFile();
    BMPFile(const QString& fileName);
//    void setTargetFileName(const QString& fileName);
    bool compare(CharacterVector *pCharactor,double& similarity);
    bool compare(BMPFile& other,double& similarity);
    bool binarizing(char* pOutChar,int& nLen);
    bool getCharactor(CharacterVector *pCharactor,const int maxSize);
    void setGetAlgorithm(int index);
    void setDBAdapter(const database_type& pDB);
    void setLastName(const QString& name);
    void setRecogniseAlgorithm(int index);
    bool stepExec(int index);

    //get
    void getRepoInfo(RepositoryInfo_t& repoInfo)const;
    void getSimilarity(double& d)const;
    void xiaoboguolv();
    void pca();


private:
    bool stepFindInner();
    bool stepFindOuter();
    bool stepDLInsAlgorithm();
    bool stepLOGBin();
    bool stepMorphological();
    bool stepGetCharactor();
    bool stepSaveCharactor();
    bool stepRecognise();

private:
    bool init();
    void initMap();
    void findMaxNum(CharacterVector* pCharactor,int maxSize);
    bool start();
    void reset();
    bool readBuf();
    bool getFileHeader();
    bool getInfoHeader();
    inline void getMinThreshold(char* pChar,
            int& minIndex, int& nThreshold);
    inline bool drainCircle(char* pChar,CIRCLE circle);
    inline bool saveAsBmp(char* pChar,int nSize);
    inline bool saveCharaToDB();
    inline bool knnRecognise();
    inline bool binarization();
    inline bool threshold();
    inline bool pupilContour(char* lpRecorder);
    inline bool findPHTPoint(LPSTR lpRecorder, listPoint_type& PHTlist);
    inline bool PHT(listPoint_type& PHTlist,CIRCLE& outCircle);
    inline bool findOuterCircle(CIRCLE InnerCircle,
                    CIRCLE& outCircle);
    inline bool TurnToRect(CIRCLE Inner,CIRCLE Outer,LPSTR pNewPtr);
    inline unsigned char DLInsAlgorithm(float x,float y);
    inline void LOGBin(LPSTR pNewPtr);
    inline void Morphological(LPSTR pNewPtr);
    inline void MarkthePoint(LPSTR pNewPtr,PointInformation *PointInfor,int &tab);
    inline void GetCharacterVector(PointInformation * PointInfor,
            int tab,CharacterVector *Character,int length);
    inline float Compare(CharacterVector *chara1,int Vect1,
                         CharacterVector* chara2,int Vect2);
    inline void MySaveCharaV(FileName_Chara FileName_CharaVx,int Vect);

private:
    QString             m_filePathName;
    QString             m_lastFileName;     //for save to DB
//    qint64              m_fileSize;
//    QString             m_targetFilePathName;
    file_type           m_pFile;
    BITMAPFILEHEADER    m_fileHeader;
    BITMAPINFOHEADER    m_infoHeader;
    bool                m_iIsInitiliztion;
    char*               m_pBuf;         //save source
    qint64              m_bufSize;
    char*               m_pRecorder;    //temp
    int                 m_recordSize;

    uint8                       m_threshold;
    std::map<int,StepFuncPtr>   m_mapStepFuncPtr;
    int                         m_preIndex;
    int                         m_curIndex;
    int                         m_getAlgorithmIndex;
    int                         m_recoAlgorithmIndex;
    database_type               m_pDB;
    QString                     m_pictureName;

    //get
    RepositoryInfo_t            m_repositoryInfo;
    double                      m_similarity;
    LPSTR                       lpNewRecorder;

public:
    bool                m_iIsFinished;
    CharacterVector m_pChara[CHARACTER_LENGTH];

    CIRCLE  m_innerCircle;
    CIRCLE  m_outerCircle;
};

//PCA
typedef struct sourcedata   //声明了一个PCA使用原始数据结构体
{
    int m;
    int n;
    double **data;
}SourceData;

class PCA
{
public:
    PCA(int m,int n);  //m为行数，n为列数
    SourceData getdata(double a[128][7]); //获取外部数据
    void standarddata(double **a); //数据标准化
    double  product(double *a,double *b); //向量乘积
    void  swap(double &x,double &y); //数据交换
    double  **matrixproduct(double **a); //求解协方差矩阵
    void  selectionsort(double *A,double **v); //特征值排序
    void  zhengjiao(double **v); //向量正交化
    int jcb(double **a,double **v,double eps,int jt);		 //求解特征值和特征向量
    int selectcharactor(double *A,double getratio,double *B); //提取主分量
    double  **getProject(int t,double **x,double **v);//计算投影
    void   saveProject(const char *projectfile,double **project,int t); //保存投影
    ~PCA(){}
private:
    int  rows;
    int columns;
};


#endif // BMPFILE_H
